package com.tyut.musicdreamer.service.music.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tyut.musicdreamer.service.music.model.dto.MusicCreateRequest;
import com.tyut.musicdreamer.service.music.model.dto.MusicQueryRequest;
import com.tyut.musicdreamer.service.music.model.dto.MusicUpdateRequest;
import com.tyut.musicdreamer.service.music.model.vo.MusicVO;
import com.tyut.musicdreamer.service.music.service.MusicService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;

/**
 * 音乐控制器
 */
@RestController
@RequestMapping("/api/music")
@RequiredArgsConstructor
@Slf4j
public class MusicController {
    
    private static final String USER_ID_ATTRIBUTE = "userId";
    private static final String USER_ID_HEADER = "X-User-Id";
    
    private final MusicService musicService;
    private final HttpServletRequest request;

    /**
     * 获取当前用户ID
     * 从请求头X-User-Id中获取，如果获取不到，则尝试从请求属性中获取
     * 如果都没有，则使用默认值1
     */
    private Long getCurrentUserId() {
        // 尝试从请求头中获取用户ID
        String userIdHeader = request.getHeader(USER_ID_HEADER);
        if (StringUtils.hasText(userIdHeader)) {
            try {
                log.debug("从请求头获取到用户ID: {}", userIdHeader);
                return Long.parseLong(userIdHeader);
            } catch (NumberFormatException e) {
                log.warn("请求头中的用户ID不是有效的数字: {}", userIdHeader);
            }
        }
        
        // 如果请求头中没有，则尝试从请求属性中获取
        Object userIdAttr = request.getAttribute(USER_ID_ATTRIBUTE);
        if (userIdAttr != null) {
            log.debug("从请求属性获取到用户ID: {}", userIdAttr);
            if (userIdAttr instanceof Number) {
                return ((Number) userIdAttr).longValue();
            } else if (userIdAttr instanceof String) {
                try {
                    return Long.parseLong((String) userIdAttr);
                } catch (NumberFormatException e) {
                    log.warn("请求属性中的用户ID不是有效的数字: {}", userIdAttr);
                }
            }
        }
        
        // 未获取到用户ID，返回默认值1
        log.warn("无法获取当前用户ID，使用默认值1");
        return 1L;
    }
    
    /**
     * 获取音乐列表
     */
    @GetMapping("/list")
    public Page<MusicVO> listMusic(MusicQueryRequest request) {
        log.debug("分页查询音乐, 页码: {}, 每页数量: {}", request.getPageNum(), request.getPageSize());
        return musicService.pageMusicList(request);
    }

    /**
     * 获取音乐详情
     */
    @GetMapping("/{id}")
    public MusicVO getMusicById(@PathVariable String id) {
        log.debug("获取音乐详情, 音乐ID: {}", id);
        return musicService.getMusicById(id);
    }

    /**
     * 获取我的音乐列表
     */
    @GetMapping("/my")
    public List<MusicVO> getMyMusicList() {
        Long userId = getCurrentUserId();
        log.debug("获取我的音乐列表, 用户ID: {}", userId);
        return musicService.getMusicListByUserId(userId);
    }

    /**
     * 创建音乐
     */
    @PostMapping("/create")
    public MusicVO createMusic(@RequestBody MusicCreateRequest request) {
        Long userId = getCurrentUserId();
        log.debug("创建音乐, 用户ID: {}, 标题: {}", userId, request.getTitle());
        request.setUserId(userId);
        return musicService.createMusic(request);
    }

    /**
     * 更新音乐
     */
    @PutMapping("/{id}")
    public MusicVO updateMusic(@PathVariable String id, @RequestBody MusicUpdateRequest request) {
        Long userId = getCurrentUserId();
        log.debug("更新音乐, 音乐ID: {}, 用户ID: {}", id, userId);
        request.setId(id);
        return musicService.updateMusic(request);
    }

    /**
     * 删除音乐
     */
    @DeleteMapping("/{id}")
    public boolean deleteMusic(@PathVariable String id) {
        Long userId = getCurrentUserId();
        log.debug("删除音乐, 音乐ID: {}, 用户ID: {}", id, userId);
        return musicService.deleteMusic(id, userId);
    }

    /**
     * 上传音乐
     */
    @PostMapping("/upload")
    public MusicVO uploadMusic(@RequestParam("file") MultipartFile file,
                               @RequestParam(value = "cover", required = false) MultipartFile cover,
                               @RequestParam(value = "title", required = false) String title,
                               @RequestParam(value = "artist", required = false) String artist,
                               @RequestParam(value = "album", required = false) String album,
                               @RequestParam(value = "genre", required = false) String genre,
                               @RequestParam(value = "year", required = false) Integer year,
                               @RequestParam(value = "description", required = false) String description,
                               @RequestParam(value = "tags", required = false) String tags) {
        // 获取用户ID
        Long userId = getCurrentUserId();
        log.info("上传音乐请求开始处理, 用户ID: {}, 文件大小: {}, 封面: {}", 
                userId, file.getSize(), cover != null ? "有" : "无");
        
        // 记录请求参数
        log.info("上传音乐请求参数 - 标题: {}, 艺术家: {}, 专辑: {}, 流派: {}, 年份: {}, 描述: {}, 标签: {}", 
                title, artist, album, genre, year, description, tags);
        
        // 检查音乐文件
        if (file == null || file.isEmpty()) {
            log.error("音乐文件为空");
            throw new IllegalArgumentException("音乐文件不能为空");
        }
        
        // 记录音乐文件信息
        log.info("音乐文件信息 - 文件名: {}, 原始文件名: {}, 内容类型: {}, 大小: {} 字节", 
                file.getName(), file.getOriginalFilename(), file.getContentType(), file.getSize());
        
        // 检查封面文件
        if (cover != null) {
            if (cover.isEmpty()) {
                log.warn("封面文件为空");
            } else {
                log.info("封面文件信息 - 文件名: {}, 原始文件名: {}, 内容类型: {}, 大小: {} 字节", 
                        cover.getName(), cover.getOriginalFilename(), cover.getContentType(), cover.getSize());
                
                // 检查文件类型
                String contentType = cover.getContentType();
                if (contentType == null || !contentType.startsWith("image/")) {
                    log.warn("封面文件类型不正确: {}", contentType);
                }
                
                // 尝试获取封面文件内容
                try {
                    byte[] coverBytes = cover.getBytes();
                    log.info("成功读取封面文件内容，大小: {} 字节", coverBytes.length);
                } catch (IOException e) {
                    log.error("读取封面文件内容失败", e);
                }
            }
        } else {
            log.info("没有提供封面文件");
        }
        
        // 构建创建请求
        MusicCreateRequest request = new MusicCreateRequest();
        request.setTitle(title != null ? title : file.getOriginalFilename());
        request.setArtist(artist);
        request.setAlbum(album);
        request.setGenre(genre);
        request.setYear(year);
        request.setDescription(description);
        request.setTags(tags);
        request.setUserId(userId);
        
        // 上传音乐并获取结果
        MusicVO musicVO = musicService.uploadMusic(file, request);
        log.info("音乐上传成功，ID: {}", musicVO.getId());
        
        // 如果有封面，上传封面
        if (cover != null && !cover.isEmpty() && musicVO != null) {
            try {
                log.info("开始上传封面，音乐ID: {}", musicVO.getId());
                musicService.uploadMusicCover(musicVO.getId(), cover, userId);
                log.info("封面上传成功，音乐ID: {}", musicVO.getId());
                
                // 重新获取音乐信息，确保封面URL被更新
                musicVO = musicService.getMusicById(musicVO.getId());
                log.info("音乐信息已更新，封面URL: {}", musicVO.getCoverUrl());
            } catch (IOException e) {
                log.error("上传封面失败，音乐ID: {}, 错误: {}", musicVO.getId(), e.getMessage(), e);
            }
        }
        
        log.info("音乐上传请求处理完成，音乐ID: {}", musicVO.getId());
        return musicVO;
    }
    
    /**
     * 获取音乐文件
     */
    @GetMapping("/{id}/stream")
    public void streamMusic(@PathVariable String id, HttpServletResponse response) throws IOException {
        log.debug("获取音乐文件, 音乐ID: {}", id);
        musicService.streamMusic(id, response);
    }

    /**
     * 下载音乐文件
     */
    @GetMapping("/{id}/download")
    public void downloadMusic(@PathVariable String id, HttpServletResponse response) throws IOException {
        log.debug("下载音乐文件, 音乐ID: {}", id);
        musicService.downloadMusic(id, response);
    }

    /**
     * 获取音乐封面
     */
    @GetMapping("/{id}/cover")
    public void getMusicCover(@PathVariable String id, HttpServletResponse response) throws IOException {
        log.debug("获取音乐封面, 音乐ID: {}", id);
        musicService.getMusicCover(id, response);
    }

    /**
     * 上传音乐封面
     */
    @PostMapping("/{id}/cover")
    public void uploadMusicCover(@PathVariable String id, @RequestParam("file") MultipartFile file) throws IOException {
        Long userId = getCurrentUserId();
        log.debug("上传音乐封面, 音乐ID: {}, 用户ID: {}, 文件大小: {}", id, userId, file.getSize());
        musicService.uploadMusicCover(id, file, userId);
    }

    /**
     * 记录播放
     */
    @PostMapping("/{id}/play")
    public boolean play(@PathVariable String id) {
        Long userId = getCurrentUserId();
        log.debug("记录播放, 音乐ID: {}, 用户ID: {}", id, userId);
        return musicService.recordPlay(id, userId);
    }

    /**
     * 点赞音乐
     */
    @PostMapping("/{id}/like")
    public boolean likeMusic(@PathVariable String id) {
        Long userId = getCurrentUserId();
        log.debug("点赞音乐, 音乐ID: {}, 用户ID: {}", id, userId);
        return musicService.likeMusic(id, userId);
    }

    /**
     * 取消点赞
     */
    @DeleteMapping("/{id}/like")
    public boolean unlikeMusic(@PathVariable String id) {
        Long userId = getCurrentUserId();
        log.debug("取消点赞, 音乐ID: {}, 用户ID: {}", id, userId);
        return musicService.unlikeMusic(id, userId);
    }

    /**
     * 收藏音乐
     */
    @PostMapping("/{id}/favorite")
    public boolean favoriteMusic(@PathVariable String id) {
        Long userId = getCurrentUserId();
        log.debug("收藏音乐, 音乐ID: {}, 用户ID: {}", id, userId);
        return musicService.favoriteMusic(id, userId);
    }

    /**
     * 取消收藏
     */
    @DeleteMapping("/{id}/favorite")
    public boolean unfavoriteMusic(@PathVariable String id) {
        Long userId = getCurrentUserId();
        log.debug("取消收藏, 音乐ID: {}, 用户ID: {}", id, userId);
        return musicService.unfavoriteMusic(id, userId);
    }

    /**
     * 获取用户收藏的音乐列表
     */
    @GetMapping("/favorites")
    public Page<MusicVO> getUserFavorites(
            @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        Long userId = getCurrentUserId();
        log.debug("获取用户收藏的音乐列表, 用户ID: {}, 页码: {}, 每页数量: {}", userId, pageNum, pageSize);
        return musicService.getUserFavorites(userId, pageNum, pageSize);
    }

    /**
     * 获取音乐文件URL
     */
    @GetMapping("/{id}/url")
    public String getMusicFileUrl(@PathVariable String id, 
                              @RequestParam(value = "type", defaultValue = "music") String type,
                              @RequestParam(value = "expirationMinutes", defaultValue = "60") Integer expirationMinutes) {
        log.debug("获取音乐文件URL, 音乐ID: {}, 类型: {}, 过期时间: {}分钟", id, type, expirationMinutes);
        
        // 获取音乐详情
        MusicVO music = musicService.getMusicById(id);
        
        // 根据类型获取URL
        if ("cover".equals(type)) {
            if (music.getCoverUrl() != null && StringUtils.hasLength(music.getCoverUrl())) {
                return musicService.getPresignedUrl(music.getCoverUrl(), expirationMinutes);
            }
            return null;
        }
        
        // 默认返回音乐文件URL
        if (music.getFileUrl() != null) {
            return musicService.getPresignedUrl(music.getFileUrl(), expirationMinutes);
        }
        
        return null;
    }
    
    /**
     * 获取随机音乐列表
     * 
     * @param count 获取数量，默认为10，最大50
     * @return 随机音乐列表
     */
    @GetMapping("/random-list")
    public List<MusicVO> getRandomMusic(
            @RequestParam(value = "count", defaultValue = "10") Integer count) {
        Long userId = getCurrentUserId();
        log.debug("获取随机音乐列表, 数量: {}, 用户ID: {}", count, userId);
        return musicService.getRandomMusic(count, userId);
    }
} 